﻿using DevExpress.Drawing.Printing;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraPrinting;
using DevExpress.XtraPrinting.BarCode;
using DevExpress.XtraReports.UI;
using MesProjectWinform.Helper;
using MesProjectWinform.Public;
using MesProjectWinform.Public.Common;
using MesProjectWinform.WareHouse.Entity;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
using static DevExpress.Xpo.Helpers.AssociatedCollectionCriteriaHelper;
using static System.Runtime.CompilerServices.RuntimeHelpers;

namespace MesProjectWinform.WareHouse.Form.来料标签打印
{
    public partial class Form_TagLabelPrint : DevExpress.XtraEditors.XtraForm
    {
        private HttpClientHelper _httpClient;
        private LabelPrintModel _labelPrintModel;
        private bool isQRCode = true; // 默认使用二维码，false则使用条形码

        // 解析规则字典，存储不同的规则模板
        private Dictionary<string, string> _parseRules = new Dictionary<string, string>();
        
        // 字段代码映射字典
        private Dictionary<string, string> _fieldCodeMap = new Dictionary<string, string>();

        public Form_TagLabelPrint()
        {
            InitializeComponent();
            _httpClient = new HttpClientHelper();
            _labelPrintModel = new LabelPrintModel();
            InitializeControls();
        }

        private void InitializeControls()
        {
            // 初始化控件
            cmbSource.Properties.Items.AddRange(new[] { "采购", "客供料"});
            cmbSource.SelectedIndex = 0;

            // 绑定事件
            btnPrint.Click += BtnPrint_Click;
            cmbSource.SelectedIndexChanged += CmbSource_SelectedIndexChanged;
            cmbSupplier.SelectedIndexChanged += CmbSupplier_SelectedIndexChanged;
            
            // 初始化日期控件
            dtpProduction.EditValue = DateTime.Now;
            dtpExpiry.EditValue = DateTime.Now.AddMonths(6);
            
            // 初始化打印类型
            rbtQRCode.Checked = true;
            rbtBarcode.Checked = false;
            
            rbtQRCode.CheckedChanged += RbtPrintType_CheckedChanged;
            rbtBarcode.CheckedChanged += RbtPrintType_CheckedChanged;

            // 绑定解析相关事件
            txtExternalTagCode.TextChanged += TxtExternalTagCode_TextChanged;
            cmbParseRule.SelectedIndexChanged += CmbParseRule_SelectedIndexChanged;
            
            // 初始化字段代码映射
            InitFieldCodeMapping();
            
            // 加载供应商信息
            LoadSuppliers();
        }
        
        /// <summary>
        /// 初始化字段代码和对应字段的映射关系
        /// </summary>
        private void InitFieldCodeMapping()
        {
            _fieldCodeMap.Clear();
            _fieldCodeMap.Add("T9824", "有效日期");
            _fieldCodeMap.Add("T2187", "生产日期");
            _fieldCodeMap.Add("T9664", "规格");
            _fieldCodeMap.Add("T3929", "批次号");
            _fieldCodeMap.Add("T0554", "数量");
            _fieldCodeMap.Add("T2174", "料号");
            _fieldCodeMap.Add("T4500", "物料编码");
            _fieldCodeMap.Add("T7095", "Reel编码");
            _fieldCodeMap.Add("T1346", "供应商编码");
            _fieldCodeMap.Add("T9579", "唯一码");
            _fieldCodeMap.Add("T6588", "寿命");
            _fieldCodeMap.Add("T0849", "箱号");
        }

        private void CmbParseRule_SelectedIndexChanged(object sender, EventArgs e)
        {
            // 规则改变时重新解析
            string tagCode = txtExternalTagCode.Text.Trim();
            if (string.IsNullOrEmpty(tagCode)) return;
            
            // 当选中新的解析规则时，先清除相关字段的值
            // txtDeliveryOrder.Text = "";
            // txtQuantity.Text = "";
            // txtBatchNumber.Text = "";
            // txtMaterial.Text = "";
            // 不清空字段，而是尝试解析当前标签
            
            ParseExternalTagCode();
        }

        /// <summary>
        /// 解析标签中的所有字段
        /// </summary>
        private void ParseAllFields()
        {
            string tagCode = txtExternalTagCode.Text.Trim();
            if (string.IsNullOrEmpty(tagCode)) return;
            
            // 遍历所有已知的字段代码
            foreach (string fieldCode in _fieldCodeMap.Keys)
            {
                // 尝试在标签中查找该字段代码
                if (tagCode.Contains(fieldCode))
                {
                    // 提取字段值
                    int startPos = tagCode.IndexOf(fieldCode) + fieldCode.Length;
                    if (startPos < tagCode.Length)
                    {
                        string remainingText = tagCode.Substring(startPos);
                        string fieldValue = "";
                        
                        // 获取直到下一个字段代码或空格的值
                        foreach (char c in remainingText)
                        {
                            if (char.IsWhiteSpace(c)) break;
                            
                            // 检查是否是下一个字段代码的开始
                            bool isNextCode = false;
                            if (c == 'T' && remainingText.IndexOf(c) < remainingText.Length - 4)
                            {
                                string possibleCode = remainingText.Substring(remainingText.IndexOf(c), 5);
                                if (_fieldCodeMap.ContainsKey(possibleCode))
                                {
                                    isNextCode = true;
                                }
                            }
                            
                            if (isNextCode) break;
                            fieldValue += c;
                        }
                        
                        if (!string.IsNullOrEmpty(fieldValue))
                        {
                            ProcessFieldValue(fieldCode, fieldValue);
                        }
                    }
                }
            }
        }

        private void TxtExternalTagCode_TextChanged(object sender, EventArgs e)
        {
            // 外部标签文本改变时重新解析
            ParseExternalTagCode();
            
            // 尝试解析所有可能的字段
            ParseAllFields();
        }

        /// <summary>
        /// 根据选择的解析规则，解析外部标签条形码
        /// </summary>
        private void ParseExternalTagCode()
        {
            try
            {
                string tagCode = txtExternalTagCode.Text.Trim();
                if (string.IsNullOrEmpty(tagCode)) return;

                string selectedRule = cmbParseRule.Text;
                if (string.IsNullOrEmpty(selectedRule)) return;

                // 从选中规则中提取字段代码
                string fieldCode;
                if (selectedRule.StartsWith("T") && selectedRule.Length > 4)
                {
                    fieldCode = selectedRule.Substring(0, 5).Trim(); // T + 4位数字
                }
                else
                {
                    // 如果不是标准字段代码格式，尝试传统解析
                    TryLegacyParsing(tagCode, selectedRule);
                    return;
                }

                // 尝试在标签码中查找字段代码
                int codeIndex = tagCode.IndexOf(fieldCode);
                if (codeIndex >= 0)
                {
                    // 提取字段值 - 假设值在代码后直到下一个字段代码或结束
                    string remainingText = tagCode.Substring(codeIndex + fieldCode.Length);
                    string fieldValue = remainingText;

                    // 查找下一个可能的字段代码位置
                    foreach (string nextCode in _fieldCodeMap.Keys)
                    {
                        int nextCodePos = remainingText.IndexOf(nextCode);
                        if (nextCodePos > 0 && nextCodePos < fieldValue.Length)
                        {
                            fieldValue = remainingText.Substring(0, nextCodePos);
                        }
                    }

                    // 清理可能的空格和特殊字符
                    fieldValue = fieldValue.Trim();
                    
                    // 根据字段代码处理值
                    ProcessFieldValue(fieldCode, fieldValue);
                }
                else
                {
                    // 尝试使用正则表达式
                    TryRegexParsing(tagCode, fieldCode);
                }
            }
            catch (Exception ex)
            {
                // 解析失败时不显示错误，静默处理
                Console.WriteLine($"解析标签失败: {ex.Message}");
            }
        }
        
        /// <summary>
        /// 使用正则表达式尝试解析标签
        /// </summary>
        private void TryRegexParsing(string tagCode, string fieldCode)
        {
            // 尝试不同的正则模式
            string[] patterns = {
                fieldCode + @"([^\s]+)",                  // 代码后紧跟值
                fieldCode + @"\s*[:=\-]?\s*([^\s]+)",     // 代码后可能有分隔符
                fieldCode + @"\s*[:=\-]?\s*([^T]+)"       // 直到下一个T开头的代码
            };
            
            foreach (string pattern in patterns)
            {
                Match match = Regex.Match(tagCode, pattern);
                if (match.Success)
                {
                    string fieldValue = match.Groups[1].Value.Trim();
                    ProcessFieldValue(fieldCode, fieldValue);
                    return;
                }
            }
            
            // 如果正则匹配失败，尝试查找字段代码后的任何非空白字符
            int codePos = tagCode.IndexOf(fieldCode, StringComparison.OrdinalIgnoreCase);
            if (codePos >= 0)
            {
                int valueStart = codePos + fieldCode.Length;
                if (valueStart < tagCode.Length)
                {
                    // 提取代码后的字符，直到空白或其他字段代码
                    string remainingText = tagCode.Substring(valueStart).Trim();
                    string fieldValue = "";
                    
                    foreach (char c in remainingText)
                    {
                        if (char.IsWhiteSpace(c) || (c == 'T' && remainingText.IndexOf(c) > 0))
                            break;
                        fieldValue += c;
                    }
                    
                    if (!string.IsNullOrEmpty(fieldValue))
                    {
                        ProcessFieldValue(fieldCode, fieldValue);
                    }
                }
            }
        }
        
        /// <summary>
        /// 处理字段值并设置到对应控件
        /// </summary>
        private void ProcessFieldValue(string fieldCode, string fieldValue)
        {
            if (!_fieldCodeMap.ContainsKey(fieldCode)) return;
            
            string fieldName = _fieldCodeMap[fieldCode];
            
            switch (fieldName)
            {
                case "有效日期":
                    if (TryParseDate(fieldValue, out DateTime expDate))
                    {
                        dtpExpiry.DateTime = expDate;
                    }
                    break;
                    
                case "生产日期":
                    if (TryParseDate(fieldValue, out DateTime prodDate))
                    {
                        dtpProduction.DateTime = prodDate;
                    }
                    break;
                    
                case "规格":
                    // 可以添加一个规格字段或者处理到已有字段
                    break;
                    
                case "批次号":
                    txtBatchNumber.Text = fieldValue;
                    break;
                    
                case "数量":
                    txtQuantity.Text = fieldValue;
                    break;
                    
                case "料号":
                case "物料编码":
                    txtMaterial.Text = fieldValue;
                    break;
                    
                case "唯一码":
                case "Reel编码":
                    // 可以添加对应字段处理
                    break;
                    
                case "供应商编码":
                    // 根据供应商编码查找对应的供应商
                    SetSupplierByCode(fieldValue);
                    break;
                    
                case "箱号":
                    txtDeliveryOrder.Text = fieldValue;
                    break;
            }
        }
        
        /// <summary>
        /// 尝试使用传统方式解析标签代码
        /// </summary>
        private void TryLegacyParsing(string tagCode, string selectedRule)
        {
            if (!_parseRules.ContainsKey(selectedRule)) return;
            
            string separator = _parseRules[selectedRule];
            string[] parts = tagCode.Split(new[] { separator }, StringSplitOptions.None);

            // 确保解析出足够的部分
            if (parts.Length >= 5)
            {
                // 设置送货单号（单号）
                txtDeliveryOrder.Text = parts[0];

                // 设置每份数量（数量）
                txtQuantity.Text = parts[1];

                // 设置批次号（批号）
                txtBatchNumber.Text = parts[2];

                // 解析生产日期
                if (TryParseDate(parts[3], out DateTime prodDate))
                {
                    dtpProduction.DateTime = prodDate;
                }

                // 解析失效日期
                if (TryParseDate(parts[4], out DateTime expDate))
                {
                    dtpExpiry.DateTime = expDate;
                }
            }
        }
        
        /// <summary>
        /// 尝试解析各种格式的日期字符串
        /// </summary>
        private bool TryParseDate(string dateStr, out DateTime result)
        {
            // 删除可能存在的字母，比如20250705B中的B
            string cleanDate = new string(dateStr.Where(c => char.IsDigit(c) || c == '-' || c == '/' || c == '.').ToArray());
            
            // 如果已经是yyyy-MM-dd或类似格式，直接尝试解析
            if (cleanDate.Contains("-") || cleanDate.Contains("/") || cleanDate.Contains("."))
            {
                return DateTime.TryParse(cleanDate, out result);
            }
            
            // 处理yyyyMMdd格式
            if (cleanDate.Length >= 8)
            {
                string formattedDate = $"{cleanDate.Substring(0, 4)}-{cleanDate.Substring(4, 2)}-{cleanDate.Substring(6, 2)}";
                return DateTime.TryParse(formattedDate, out result);
            }
            
            result = DateTime.Now;
            return false;
        }
        
        /// <summary>
        /// 根据供应商编码设置选择的供应商
        /// </summary>
        private void SetSupplierByCode(string supplierCode)
        {
            for (int i = 0; i < cmbSupplier.Properties.Items.Count; i++)
            {
                string item = cmbSupplier.Properties.Items[i].ToString();
                if (item.Contains($"({supplierCode})"))
                {
                    cmbSupplier.SelectedIndex = i;
                    break;
                }
            }
        }

        private void RbtPrintType_CheckedChanged(object sender, EventArgs e)
        {
            RadioButton rb = sender as RadioButton;
            if (rb != null && rb.Checked)
            {
                isQRCode = rb.Name == "rbtQRCode";
            }
        }

        private async void LoadSuppliers()
        {
            try
            {
                cmbSupplier.Properties.Items.Clear();

                try
                {
                    HttpClientHelper helper = new HttpClientHelper();
                    string json = helper.RequestUrlNew(RequestType.Get, "WareHouse/BasicInfo/GetSupplier", null);
                    ApiResult<List<SupplierModel>> result = JsonConvert.DeserializeObject<ApiResult<List<SupplierModel>>>(json);

                    if (result != null && result.Code == ApiEnums.Success && result.Data != null)
                    {
                        foreach (var supplier in result.Data)
                        {
                            cmbSupplier.Properties.Items.Add($"({supplier.SupplierId}){supplier.SupplierName}");
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("加载供应商数据时发生错误：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }


                // 如果有项，选择第一项
                if (cmbSupplier.Properties.Items.Count > 0)
                {
                    cmbSupplier.SelectedIndex = 0;
                }
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show($"加载供应商信息失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void CmbSource_SelectedIndexChanged(object sender, EventArgs e)
        {
            // 根据来源不同，可能需要调整UI显示
        }

        private void CmbSupplier_SelectedIndexChanged(object sender, EventArgs e)
        {
            // 选择供应商后的处理
            string selectedItem = cmbSupplier.SelectedItem?.ToString();
            if (!string.IsNullOrEmpty(selectedItem))
            {
                // 解析供应商编码和名称
                int startIndex = selectedItem.IndexOf('(') + 1;
                int endIndex = selectedItem.IndexOf(')');
                if (startIndex > 0 && endIndex > startIndex)
                {
                    string supplierCode = selectedItem.Substring(startIndex, endIndex - startIndex);
                    string supplierName = selectedItem.Substring(endIndex + 1);
                    
                    _labelPrintModel.SupplierId = supplierCode;
                    _labelPrintModel.SupplierName = supplierName;
                    TagRu();
                }
            }
        }

        private async void TagRu()
        {
            _parseRules.Clear();
            cmbParseRule.Properties.Items.Clear();
            string supplierCode = _labelPrintModel.SupplierId;
            string action = $"WareHouse/Label/GetLabel?pageNum=0&QryID={supplierCode}";
            HttpClientHelper helper = new HttpClientHelper();
            // 调用API
            string json = helper.RequestUrlNew(RequestType.Get, action, null);
            ApiPaging<List<LableModel>> model = JsonConvert.DeserializeObject<ApiPaging<List<LableModel>>>(json);
            if (model != null && model.Code == ApiEnums.Success && model.Data != null)
            {
                foreach (var supplier in model.Data)
                {
                    _parseRules.Add(supplier.FormatMemo, supplier.Delimiter);
                    
                    // 字段代码格式：Txxxx 描述
                    if (supplier.FormatMemo.StartsWith("T") && supplier.FormatMemo.Length > 4)
                    {
                        string code = supplier.FormatMemo.Substring(0, 5); // 提取代码部分 (T加4位数字)
                        string description = supplier.FormatMemo.Substring(5).Trim(); // 提取描述部分
                        
                        // 更新字段代码映射
                        if (!_fieldCodeMap.ContainsKey(code))
                        {
                            _fieldCodeMap[code] = description;
                        }
                    }
                    
                    cmbParseRule.Properties.Items.Add(supplier.FormatMemo);
                }
            }
            
            // 如果有项，选择第一项
            if (cmbParseRule.Properties.Items.Count > 0)
            {
                cmbParseRule.SelectedIndex = 0;
            }
        }

        private void BtnPrint_Click(object sender, EventArgs e)
        {
            try
            {
                // 验证输入
                if (string.IsNullOrEmpty(txtDeliveryOrder.Text))
                {
                    XtraMessageBox.Show("送货单号不能为空！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                if (string.IsNullOrEmpty(txtMaterial.Text))
                {
                    XtraMessageBox.Show("物料不能为空！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                if (!int.TryParse(txtQuantity.Text, out int quantity) || quantity <= 0)
                {
                    XtraMessageBox.Show("每份数量必须为正整数！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                if (!int.TryParse(txtCopies.Text, out int copies) || copies <= 0)
                {
                    XtraMessageBox.Show("打印个数必须为正整数！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                // 收集标签信息
                _labelPrintModel.Source = cmbSource.Text;
                _labelPrintModel.DeliverNum = txtDeliveryOrder.Text;
                _labelPrintModel.TagBarCode = txtExternalTagCode.Text;
                _labelPrintModel.Material = txtMaterial.Text;
                _labelPrintModel.Batchcode = txtBatchNumber.Text;
                _labelPrintModel.ManuDate = dtpProduction.DateTime.ToString("yyyy-MM-dd");
                _labelPrintModel.Expiration = dtpExpiry.DateTime.ToString("yyyy-MM-dd");
                _labelPrintModel.PrintNum = copies;

                // 生成并打印标签
                GenerateAndPrintLabels(_labelPrintModel, copies);
                
                // 保存打印记录到数据库
                SavePrintRecord(_labelPrintModel);
                
                XtraMessageBox.Show("标签打印成功！", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show($"打印过程中发生错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void GenerateAndPrintLabels(LabelPrintModel model, int copies)
        {
            // 创建XtraReport1实例
            XtraReport1 report = new XtraReport1();
            report.PaperKind = DXPaperKind.Custom;
            report.PageHeight = 350; // 增加标签高度，给条形码留出更多空间
            report.PageWidth = 300;  // 标签宽度，单位为百分之一英寸
            report.Margins = new System.Drawing.Printing.Margins(10, 10, 10, 10);

            // 调整布局，确保日期信息在条码的下方，而不是与条码重叠
            report.lblDates.LocationF = new PointF(10F, 170F); // 将日期信息往下移动，在条码下方

            // 直接访问报表中的控件并设置值
            // 标题
            report.lblTitle.Text = "物料标签";
            
            // 物料信息
            report.lblMaterial.Text = $"物料: {model.Material}";
            
            // 送货单信息
            report.lblDelivery.Text = $"送货单: {model.DeliverNum}";
            
            // 供应商信息
            report.lblSupplier.Text = $"供应商: {model.SupplierName}";

            // 日期信息
            report.lblDates.Text = $"生产日期: {model.ManuDate} 失效日期: {model.Expiration}";

            // 条码数据 - 避免使用特殊字符如|、.、:、-
            // 原始格式: $"{model.Material}|{model.DeliverNum}|{model.Batchcode}|{model.ManuDate}|{model.Expiration}"
            // 替换分隔符为下划线，并将日期中的连字符替换为空格
            string materialPart = model.Material;
            string deliverPart = model.DeliverNum;
            string batchPart = model.Batchcode;
            string manuDatePart = model.ManuDate?.Replace("-", "");
            string expDatePart = model.Expiration?.Replace("-", "");
            
            // 使用下划线作为分隔符
            string qrCodeData = $"{materialPart}_{deliverPart}_{batchPart}_{manuDatePart}_{expDatePart}";
            
            // 条形码需要更简洁的数据，否则可能显示不全或扫描困难
            string barCodeData = $"{materialPart}{deliverPart}";
            
            // 设置二维码或条形码
            if (isQRCode)
            {
                // 显示二维码
                report.qrCode.Text = qrCodeData;
                report.qrCode.Visible = true;
                report.qrCode.BringToFront(); // 确保二维码在最上层
                
                // 隐藏条形码
                report.barCode.Visible = false;
                
                // 确保二维码尺寸和位置合适
                report.qrCode.SizeF = new SizeF(120F, 120F);
                report.qrCode.LocationF = new PointF(40F, 85F);
            }
            else
            {
                // 显示条形码
                report.barCode.Text = barCodeData;
                report.barCode.Visible = true;
                report.barCode.BringToFront(); // 确保条形码在最上层
                
                // 隐藏二维码
                report.qrCode.Visible = false;
                
                // 确保条形码尺寸和位置合适
                report.barCode.SizeF = new SizeF(180F, 70F);
                report.barCode.LocationF = new PointF(10F, 85F);
                
                // 设置条码属性
                try {
                    // 尝试访问和设置条码的其他属性
                    report.barCode.AutoModule = true;
                    report.barCode.ShowText = true;
                } catch (Exception) {
                    // 如果无法设置这些属性，忽略异常
                }
            }

            // 设置打印参数
            ReportPrintTool printTool = new ReportPrintTool(report);
            printTool.PrintingSystem.StartPrint += (s, e) => 
            {
                e.PrintDocument.PrinterSettings.Copies = (short)copies;
            };

            // 执行打印
            printTool.ShowPreviewDialog();
        }

        private async void SavePrintRecord(LabelPrintModel model)
        {
            try
            {
                // 设置创建时间等信息
                model.CreatedTime = DateTime.Now;
                model.UpdatedTime = DateTime.Now;
                model.IsEnable = true;
                model.CreatedBy = RequestUser.CurrentUser.UserId;// "00"; // 应该从登录信息获取
                string postData = JsonConvert.SerializeObject(model);
                // 调用API保存记录
                // 示例代码，实际应替换为真实API调用
                HttpClientHelper helper = new HttpClientHelper();
                string json = helper.RequestUrlNew(RequestType.Post, "WareHouse/LablePrint/AddLabel", postData);
                ApiResult<int> result = JsonConvert.DeserializeObject<ApiResult<int>>(json);
                if (result != null && result.Code == ApiEnums.Success)
                {
                    //XtraMessageBox.Show($"保存打印记录失败: {result.Message}", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }

            }
            catch (Exception ex)
            {
                XtraMessageBox.Show($"保存打印记录失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

    }
}
